package asia.redact.bracket.properties;

import java.util.AbstractMap;
import java.util.Collection;
import java.util.Set;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * These are the map-like facade methods
 * 
 * @author Dave
 *
 */
public abstract class AbstractPropertiesBase {
	
	protected AbstractMap<String,ValueModel> map;
	protected final Lock lock = new ReentrantLock();

	public int size() {
		lock.lock();
		try{
			return map.size();
		}finally{
			lock.unlock();
		}
	}

	public boolean isEmpty() {
		lock.lock();
		try{
			return map.isEmpty();
		}finally{
			lock.unlock();
		}
	}

	public boolean containsKey(String key) {
		lock.lock();
		try{
			return map.containsKey(key);
		}finally{
			lock.unlock();
		}
	}

	public boolean containsValue(String value) {
		lock.lock();
		try{
			return map.containsValue(value);
		}finally{
			lock.unlock();
		}
	}

	public Object remove(String key) {
		lock.lock();
		try{
			return map.remove(key);
		}finally{
			lock.unlock();
		}
	}

	public void clear() {
		lock.lock();
		try{
			map.clear();
		}finally{
			lock.unlock();
		}
	}

	public Set<String> keySet() {
		lock.lock();
		try{
			return map.keySet();
		}finally{
			lock.unlock();
		}
	}

	public Collection<ValueModel> values() {
		lock.lock();
		try{
			return map.values();
		}finally{
			lock.unlock();
		}
	}
	
	public String toString(){
		lock.lock();
		try{
			return map.toString();
		}finally{
			lock.unlock();
		}
	}

	@Override
	public int hashCode() {
		lock.lock();
		try{
			final int prime = 31;
			int result = 1;
			result = prime * result + ((map == null) ? 0 : map.hashCode());
			return result;
		}finally{
			lock.unlock();
		}
	}

	@Override
	public boolean equals(Object obj) {
		lock.lock();
		try{
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			AbstractPropertiesBase other = (AbstractPropertiesBase) obj;
			if (map == null) {
				if (other.map != null)
					return false;
			} else if (!map.equals(other.map))
				return false;
			return true;
		}finally{
			lock.unlock();
		}
	}
	
}
